﻿using System;
using System.Diagnostics;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;
using BGShell.Components;
using BGShell.Configuration;
using WindowsFormsAero;

namespace BGShell
{
    public sealed class BGShellApplication : ApplicationContext
    {
        private BGShellAddInManager _addIns;
        private BGShellArgumentParser _arguments;
        private BGShellNotifyIcon _notifyIcon;
        private BGShellWindowManager _windows;

        private readonly BGShellSection _config = BGShellSection.GetCurrent();

        private BGShellApplication(String[] args)
        {
            _addIns = new BGShellAddInManager(_config);
            _arguments = new BGShellArgumentParser(args);
            _windows = new BGShellWindowManager(this);
        }

        public void AddNotifyIconCommand(String text, EventHandler onClick)
        {
            if (_notifyIcon != null)
            {
                _notifyIcon.AddAddinCommand(text, onClick);
            }
        }

        public void ActivateBackgroundWindow()
        {
            var window = Windows.BackgroundWindow;

            if (window != null)
            {
                window.Show();

                if (window.WindowState == FormWindowState.Minimized)
                {
                    window.WindowState = FormWindowState.Normal;
                }

                window.BringToFront();
                window.Activate();
            }
            else
            {
                throw new InvalidOperationException();
            }
        }

        public void Exit(int exitCode)
        {
            ExitCode = exitCode;
            ExitThread();
        }

        public KeyboardHook KeyboardHook
        {
            get
            {
                if (Windows.BackgroundWindow == null)
                {
                    throw new InvalidOperationException(Resources.NoBackgroundWindow);
                }

                return Windows.BackgroundWindow.KeyboardHook;
            }
        }

        public BGShellArgumentParser Arguments
        {
            get { return _arguments; }
        }

        public BGShellWindowManager Windows
        {
            get { return _windows; }
        }

        internal BGShellAddInManager AddInManager
        {
            get { return _addIns; }
        }

        internal Int32 ExitCode
        {
            get;
            set;
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_notifyIcon != null)
                {
                    _notifyIcon.Dispose();
                }
            }

            base.Dispose(disposing);
        }

        private int Run()
        {
            if (Arguments.IsBackground)
            {
                _notifyIcon = new BGShellNotifyIcon()
                {
                    Visible = true,
                };

                Windows.OpenBackground();
            }
            else
            {
                Windows.Open();
            }

            _addIns.InitializeAddins(this);

            Application.Run(this);
            return ExitCode;
        }

        public static BGShellApplication Current
        {
            get;
            private set;
        }

        [STAThread]
        private static Int32 Main(String[] args)
        {
            Application.SetCompatibleTextRenderingDefault(false);
            ToolStripManager.Renderer = new TabStripAeroRenderer();

            using (Current = new BGShellApplication(args))
            {
                return Current.Run();
            }
        }
    }

    public static class BGShellApplicationInfo
    {
        public static string Version
        {
            get
            {
                var versionInfo = FileVersion;
                return versionInfo.ProductName + " (" + versionInfo.FileVersion + ')';
            }
        }

        public static string Copyright
        {
            get
            {
                var asm = typeof(BGShellApplication).Assembly;
                var attrs = asm.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);

                if ((attrs != null) && (attrs.Length > 0))
                {
                    var a = attrs[0] as AssemblyCopyrightAttribute;

                    if (a != null)
                    {
                        return a.Copyright;
                    }
                }

                return string.Empty;
            }
        }

        public static string ExecutablePath
        {
            get { return typeof(BGShellApplication).Assembly.ManifestModule.FullyQualifiedName; }
        }

        public static FileVersionInfo FileVersion
        {
            get { return FileVersionInfo.GetVersionInfo(ExecutablePath); }
        }

        public static Icon Icon
        {
            get { return ResourcesNative.BGShellIcon; }
        }
    }
}